﻿namespace com.game.module.Dungeon
{
    using com.game;
    using com.game.basic;
    using com.game.basic.events;
    using com.game.data;
    using com.game.manager;
    using com.game.module.core;
    using com.game.module.Dungeon.DungeonTask;
    using com.game.module.map;
    using com.game.Public.Message;
    using com.game.utils;
    using com.game.vo;
    using com.u3d.bases.ai;
    using com.u3d.bases.display.vo;
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class DungeonMgr
    {
        private int _curDungeonId = -1;
        private SysDungeonVo _curDungeonSysVo;
        private SysDungeonMissionVo _curMissionInfo;
        private float _endTime;
        private static DungeonMgr _inst;
        private bool _isOver;
        private bool _isPlaying;
        private float _lastSubmitTime;
        private ushort _numMonterKilled;
        private int _numSubmit;
        private bool _success;
        private float _time;

        private bool CheckDungeonFail(int type, int v1, int v2, object data)
        {
            bool flag = false;
            switch (type)
            {
                case 2:
                    return this.CheckFailByDeath();

                case 8:
                {
                    MTask mainTask = Singleton<MTaskMgr>.Instance.mainTask;
                    if (mainTask.targetId != v1)
                    {
                        return flag;
                    }
                    if (mainTask.taskType != 8)
                    {
                        if (mainTask.taskType != 1)
                        {
                            return flag;
                        }
                        int num = AppMap.Instance.GetNumOfMonster((uint) mainTask.targetId, false, false, false) + Singleton<MonsterActivator>.Instance.GetNumOfMonster((uint) mainTask.targetId, false);
                        if ((num + mainTask.curValue) >= mainTask.targetValue)
                        {
                            return flag;
                        }
                    }
                    return true;
                }
            }
            return flag;
        }

        private void CheckDungeonOver(int type, int v1, int v2, object data)
        {
            bool flag = false;
            switch (type)
            {
                case 1:
                case 3:
                case 6:
                    flag = this.CheckDungeonWin(type, v1, v2, data);
                    break;

                case 2:
                case 8:
                    flag = this.CheckDungeonFail(type, v1, v2, data);
                    break;
            }
            if (flag)
            {
                this._endTime = this._time;
                if (this.curDungeonSysVo.endDialog <= 0)
                {
                    this.SendOver();
                }
            }
        }

        private bool CheckDungeonWin(int type, int v1, int v2, object data)
        {
            if (type == 1)
            {
                this._numMonterKilled = (ushort) (this._numMonterKilled + 1);
            }
            return DungeonChecker.Instance.CheckOver();
        }

        private bool CheckFailByDeath()
        {
            foreach (MeVo vo in SelfPlayerManager.instance.MePlayerVoList)
            {
                if ((vo.CurHp > 0) && !vo.isImprisoned)
                {
                    return false;
                }
            }
            return true;
        }

        public void Config()
        {
            Time.timeScale = 1f;
            this.OnChangeMap();
            if (this._curMissionInfo == null)
            {
                GlobalAPI.facade.prevNotify = null;
                GlobalAPI.facade.postNotify = null;
            }
            else
            {
                GlobalAPI.facade.prevNotify = new NoticeListener(this.UpdateTask);
                GlobalAPI.facade.postNotify = new NoticeListener(this.UpdateDungeon);
                int[] stringToInt = StringUtils.GetStringToInt(this._curMissionInfo.chest_list);
                for (int i = (stringToInt != null) ? (stringToInt.Length - 1) : -1; i >= 0; i--)
                {
                    ChestVo vo;
                    vo = new ChestVo {
                        sysId = (uint) stringToInt[i],
                        X = vo.sysVo.x * 0.001f,
                        Y = vo.sysVo.y * 0.001f,
                        Z = vo.sysVo.z * 0.001f
                    };
                    Singleton<ChestMgr>.Instance.Add(vo);
                }
            }
        }

        public void EnterDungeon(uint dupId, uint missionId)
        {
            this._curDungeonId = (int) dupId;
            this._curDungeonSysVo = BaseDataMgr.instance.getDungeon(dupId);
            this._curMissionInfo = BaseDataMgr.instance.getDungeonMission(missionId);
            this._isOver = false;
            this._endTime = 0f;
        }

        public void EnterMission(uint missionId)
        {
            this._curMissionInfo = BaseDataMgr.instance.getDungeonMission(missionId);
        }

        public void ExitDungeon(bool isDungeonRecnnect = false)
        {
            this._curDungeonId = -1;
            this._curDungeonSysVo = null;
            this._curMissionInfo = null;
            this._isOver = false;
            this._endTime = 0f;
            Singleton<MTaskMgr>.Instance.Clear();
            if (!isDungeonRecnnect)
            {
                GlobalAPI.facade.Notify(14, 0, 0, null);
            }
        }

        private void OnChangeMap()
        {
            this._isPlaying = false;
            this._time = 0f;
            this._numMonterKilled = 0;
            this._success = false;
            Singleton<MTaskMgr>.Instance.Reset(this._curMissionInfo);
            Singleton<MonsterActivator>.Instance.Enabled = false;
            if (!GlobalData.isInCopy && this.isInDungeon)
            {
                this.ExitDungeon(true);
            }
        }

        public void Pause()
        {
            if (this._isPlaying)
            {
                this._isPlaying = false;
                Singleton<MonsterActivator>.Instance.Enabled = false;
                GlobalAPI.facade.Notify(10, 0, 0, null);
            }
        }

        public void QuickSendOver(int star)
        {
            if (this.isInDungeon)
            {
                if (this.time < 5f)
                {
                    MessageManager.Show("副本时间5s后再使用通关");
                }
                else
                {
                    this._success = Singleton<MTaskMgr>.Instance.mainTask.isFinished;
                    GlobalAPI.facade.Notify(12, 0, 0, null);
                    this._lastSubmitTime = RealTime.time;
                    this._numSubmit++;
                    this.Stop();
                    Singleton<DungeonMode>.Instance.QuickEndDungeon(star);
                }
            }
        }

        public void Resume()
        {
            if (!this._isPlaying)
            {
                Time.timeScale = 1f;
                this._isPlaying = true;
                Singleton<MonsterActivator>.Instance.Enabled = true;
                GlobalAPI.facade.Notify(10, 0, 0, null);
            }
        }

        public void SendOver()
        {
            this._success = Singleton<MTaskMgr>.Instance.mainTask.isFinished;
            GlobalAPI.facade.Notify(12, 0, 0, null);
            this._lastSubmitTime = RealTime.time;
            this._numSubmit++;
            this.Stop();
            Singleton<DungeonMode>.Instance.EndDungeon();
        }

        internal void SetSuccess(bool value)
        {
            this._success = value;
            this._numSubmit = 0;
            GlobalAPI.facade.Notify(13, 0, 0, null);
        }

        public void Start()
        {
            Time.timeScale = 1f;
            this._isPlaying = true;
            if (this._curMissionInfo != null)
            {
                Singleton<MonsterActivator>.Instance.Start();
                GlobalAPI.facade.Notify(9, 0, 0, null);
            }
        }

        public void Stop()
        {
            this._isOver = true;
            this._isPlaying = false;
            AiControllerBase.CancelAllTimer();
            Singleton<MonsterActivator>.Instance.Enabled = false;
        }

        public void Update()
        {
            if ((this._numSubmit > 0) && ((RealTime.time - this._lastSubmitTime) > 2f))
            {
                this.SendOver();
            }
            else if (this.isPlaying)
            {
                this._time += RealTime.deltaTime;
                if ((this._curDungeonSysVo.need_time > 0) && (this._time >= this._curDungeonSysVo.need_time))
                {
                    this._time = this._curDungeonSysVo.need_time;
                    this.SendOver();
                }
                else
                {
                    Singleton<MTaskMgr>.Instance.Update(0, 0, 0, null);
                    GlobalAPI.facade.Notify(11, 0, 0, null);
                }
            }
        }

        private void UpdateDungeon(int type, int v1 = 0, int v2 = 1, object data = null)
        {
            if (this.isInDungeon)
            {
                this.CheckDungeonOver(type, v1, v2, data);
            }
        }

        private void UpdateTask(int type, int v1 = 0, int v2 = 1, object data = null)
        {
            if (this.isInDungeon)
            {
                Singleton<MTaskMgr>.Instance.Update(type, v1, v2, data);
            }
        }

        public List<ushort> chestIds
        {
            get
            {
                List<ushort> list = new List<ushort>();
                foreach (ChestVo vo in Singleton<ChestMgr>.Instance.pickList)
                {
                    list.Add((ushort) vo.sysId);
                }
                return list;
            }
        }

        public int curDungeonId
        {
            get
            {
                return this._curDungeonId;
            }
        }

        public SysDungeonVo curDungeonSysVo
        {
            get
            {
                return this._curDungeonSysVo;
            }
        }

        public int curFightType
        {
            get
            {
                return ((this._curMissionInfo != null) ? this._curMissionInfo.fight_type : 0);
            }
        }

        public SysDungeonMissionVo curMissionSysVo
        {
            get
            {
                return this._curMissionInfo;
            }
        }

        public float endTime
        {
            get
            {
                return this._endTime;
            }
        }

        public static DungeonMgr Instance
        {
            get
            {
                if (_inst == null)
                {
                    _inst = new DungeonMgr();
                }
                return _inst;
            }
        }

        public bool IsFirstPlay
        {
            get
            {
                return (null == Singleton<DungeonMode>.Instance.getDungeonInfo((uint) this._curDungeonId));
            }
        }

        public bool isInDungeon
        {
            get
            {
                return (null != this._curMissionInfo);
            }
        }

        public bool isOver
        {
            get
            {
                return this._isOver;
            }
        }

        public bool isPlaying
        {
            get
            {
                return ((this.isInDungeon && this._isPlaying) && AppNet.gameNet.connected());
            }
        }

        public ushort numMonsterKilled
        {
            get
            {
                return this._numMonterKilled;
            }
        }

        public byte numStar
        {
            get
            {
                return (byte) Singleton<MTaskMgr>.Instance.numFinished;
            }
        }

        public bool success
        {
            get
            {
                return this._success;
            }
        }

        public float time
        {
            get
            {
                return this._time;
            }
        }
    }
}

